package com.mdd.admin.service.subject.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.query.MPJQueryWrapper;
import com.mdd.admin.service.subject.ISubjectService;
import com.mdd.admin.validate.common.PageParam;
import com.mdd.admin.validate.subject.SubjectParam;
import com.mdd.admin.vo.course.CourseListVo;
import com.mdd.admin.vo.subject.SubjectListVo;
import com.mdd.admin.vo.subject.SubjectDetailVo;
import com.mdd.common.core.PageResult;
import com.mdd.common.entity.course.Course;
import com.mdd.common.entity.course.CourseCategory;
import com.mdd.common.entity.subject.Subject;
import com.mdd.common.entity.subject.SubjectCourse;
import com.mdd.common.mapper.course.CourseMapper;
import com.mdd.common.mapper.subject.SubjectCourseMapper;
import com.mdd.common.mapper.subject.SubjectMapper;
import com.mdd.common.utils.ArrayUtil;
import com.mdd.common.utils.TimeUtil;
import com.mdd.common.utils.UrlUtil;
import com.mdd.common.config.GlobalConfig;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;

/**
 * 专题专区实现类
 * @author panweiliang
 */
@Service
public class SubjectServiceImpl implements ISubjectService {
        
    @Resource
    SubjectMapper subjectMapper;

    @Resource
    SubjectCourseMapper subjectCourseMapper;

    @Resource
    CourseMapper courseMapper;

    /**
     * 专题专区列表
     *
     * @author panweiliang
     * @param pageParam 分页参数
     * @param params 搜索参数
     * @return PageResult<SubjectListVo>
     */
    @Override
    public PageResult<SubjectListVo> list(PageParam pageParam, Map<String, String> params) {
        Integer page  = pageParam.getPageNo();
        Integer limit = pageParam.getPageSize();

        MPJQueryWrapper<Subject> mpjQueryWrapper = new MPJQueryWrapper<Subject>()
                .selectAll(Subject.class)
                .select("SUM(CASE WHEN sc.course_id IS NOT NULL THEN 1 ELSE 0 END) as courseCount")
                .leftJoin("?_subject_course sc ON sc.subject_id=t.id".replace("?_", GlobalConfig.knowledgePaymentTablePrefixe))
                .groupBy("t.id")
                .orderByDesc(Arrays.asList("t.sort", "t.id"));

        subjectMapper.setSearch(mpjQueryWrapper, params, new String[]{
                "like:name@t.name:str",
                "=:status@t.status:int",
        });

        IPage<SubjectListVo> iPage = subjectMapper.selectJoinPage(new Page<>(page, limit), SubjectListVo.class, mpjQueryWrapper);

        for(SubjectListVo item : iPage.getRecords()) {
            item.setCover(UrlUtil.toAbsoluteUrl(item.getCover()));
            item.setImage(UrlUtil.toAbsoluteUrl(item.getImage()));
            item.setCreateTime(TimeUtil.timestampToDate(item.getCreateTime()));
            item.setUpdateTime(TimeUtil.timestampToDate(item.getUpdateTime()));
        }

        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), iPage.getRecords());
    }

    /**
     * 专题/专区-课程列表
     *
     * @author panweiliang
     * @param subjectId 专题/专区id
     * @return List<SubjectVo>
     */
    @Override
    public List<CourseListVo> listCourse(Integer subjectId) {

        MPJQueryWrapper<Course> mpjQueryWrapper = new MPJQueryWrapper<Course>()
                .selectAll(Course.class)
                .select("teacher.name as teacherName, category.name as category")
                .innerJoin("?_subject_course sc ON sc.course_id=t.id".replace("?_", GlobalConfig.knowledgePaymentTablePrefixe))
                .leftJoin("?_teacher teacher ON teacher.id=t.teacher_id".replace("?_", GlobalConfig.knowledgePaymentTablePrefixe))
                .leftJoin("?_course_category category ON category.id=t.category_id".replace("?_", GlobalConfig.knowledgePaymentTablePrefixe))
                .eq("sc.subject_id", subjectId)
                .orderByDesc(Arrays.asList("t.sort", "t.id"));
        List<CourseListVo> courseList = courseMapper.selectJoinList(CourseListVo.class, mpjQueryWrapper);
//        List<CourseListVo> courseListVos = new LinkedList<>();
        for(CourseListVo vo : courseList) {
            vo.setCover(UrlUtil.toAbsoluteUrl(vo.getCover()));
            vo.setCreateTime(TimeUtil.timestampToDate(vo.getCreateTime()));
            vo.setUpdateTime(TimeUtil.timestampToDate(vo.getUpdateTime()));
        }
        return courseList;
    }


    /**
     * 专题专区详情
     *
     * @author panweiliang
     * @param id 主键参数
     * @return Subject
     */
    @Override
    public SubjectDetailVo detail(Integer id) {
        Subject model = subjectMapper.selectOne(
                new QueryWrapper<Subject>()
                    .eq("id", id)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在");

        SubjectDetailVo vo = new SubjectDetailVo();
        BeanUtils.copyProperties(model, vo);
        vo.setCover(UrlUtil.toAbsoluteUrl(model.getCover()));
        vo.setImage(UrlUtil.toAbsoluteUrl(model.getImage()));
        return vo;
    }

    /**
     * 专题专区新增
     *
     * @author panweiliang
     * @param subjectParam 参数
     */
    @Override
    public void add(SubjectParam subjectParam) {
        Subject model = new Subject();
        model.setName(subjectParam.getName());
        model.setCover(UrlUtil.toRelativeUrl(subjectParam.getCover()));
        model.setImage(UrlUtil.toRelativeUrl(subjectParam.getImage()));
        model.setSort(subjectParam.getSort());
        model.setStatus(subjectParam.getStatus());
        model.setCreateTime(System.currentTimeMillis() / 1000);
        model.setUpdateTime(System.currentTimeMillis() / 1000);
        subjectMapper.insert(model);
    }

    /**
     * 专题专区编辑
     *
     * @author panweiliang
     * @param subjectParam 参数
     */
    @Override
    public void edit(SubjectParam subjectParam) {
        Subject model = subjectMapper.selectOne(
                new QueryWrapper<Subject>()
                    .eq("id",  subjectParam.getId())
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在!");
        model.setId(subjectParam.getId());
        model.setName(subjectParam.getName());
        model.setCover(UrlUtil.toRelativeUrl(subjectParam.getCover()));
        model.setImage(UrlUtil.toRelativeUrl(subjectParam.getImage()));
        model.setSort(subjectParam.getSort());
        model.setStatus(subjectParam.getStatus());
        model.setUpdateTime(System.currentTimeMillis() / 1000);
        subjectMapper.updateById(model);
    }

    /**
     * 专题专区删除
     *
     * @author panweiliang
     * @param id 主键ID
     */
    @Override
    public void del(Integer id) {
        Subject model = subjectMapper.selectOne(
                new QueryWrapper<Subject>()
                    .eq("id", id)
                    .last("limit 1"));
        Assert.notNull(model, "数据不存在!");
        subjectMapper.delete(new QueryWrapper<Subject>().eq("id", id));
        subjectCourseMapper.delete(new QueryWrapper<SubjectCourse>().eq("subject_id", id));
    }

    @Override
    public Subject changeStatus(Integer id) {
        Subject subject = subjectMapper.selectOne(
                new QueryWrapper<Subject>()
                        .eq("id", id)
                        .last("limit 1"));
        Assert.notNull(subject, "专题专区不存在!");
        subject.setStatus(subject.getStatus() == 1 ? 0 : 1);
        subject.setUpdateTime(TimeUtil.timestamp());
        subjectMapper.updateById(subject);

        subject.setCover(UrlUtil.toAbsoluteUrl(subject.getCover()));
        subject.setImage(UrlUtil.toAbsoluteUrl(subject.getImage()));
        return subject;
    }
}
